
#include "../iface/APRInterface.h"
#include "../utils/StringUtils.h"
#include "APRTable.h"

/** Constructor for the APR table.
 * 
 * @param initentries
 * The initial number of entries in the table.
 * 
 * @param imp
 * The parent memory pool from which to derive the memory pool for this object
 * from. */
APRTable::APRTable(int initentries, apr_pool_t *imp)
{
   apr_status_t status;
   status = apr_pool_create(&mp, imp);
   parent_mp = imp;
   CheckAPRError(status);
   ttable = apr_table_make(mp, initentries);
}

/** Copy constructor for the APR table object.
 * 
 * @param o
 * The other object to copy form into this object. */
APRTable::APRTable(const APRTable &o)
{
   apr_status_t status;
   status = apr_pool_create(&mp, o.parent_mp);
   parent_mp = o.parent_mp;
   CheckAPRError(status);
   ttable = apr_table_copy(mp, o.ttable);
}

/** Copy assignment operator for the APR table object.
 * 
 * @param o
 * The other object to copy form into this object. */
APRTable &APRTable::operator=(const APRTable &o)
{
   apr_status_t status;
   status = apr_pool_create(&mp, o.parent_mp);
   parent_mp = o.parent_mp;
   CheckAPRError(status);
   ttable = apr_table_copy(mp, o.ttable);
   return *this;
}

/** Destructor of the table, destroys the table and the memory pool. */
APRTable::~APRTable()
{
   apr_table_clear(ttable);
   apr_pool_destroy(mp);
}

/** Sets a key/value pair in the table.
 * 
 * @param key
 * The key string.
 * 
 * @param value
 * The value string associated with the key. */
void APRTable::set(const char *key, const char *value)
{
   apr_table_set(ttable, key, value);
}

/** Gets a value which corresponds to the given key in the table.
 * 
 * @param key
 * The key string whose value is to be obtained.
 * 
 * @return
 * The value corresponding to the given key, or NULL if the key is not
 * present. */
const char *APRTable::get(const char *key)
{
   return apr_table_get(ttable, key);
}

/** Is the table empty?
 * 
 * @return
 * Returns non-zero if the table is empty. */
int APRTable::isEmpty()
{
   return apr_is_empty_table(ttable);
}

/** Resets the table (deletes all key/value pairs). */
void APRTable::reset()
{
   return apr_table_clear(ttable);
}

/** Get a string list from the table. Caller is responsible
 * for the final destruction of the string list.
 * 
 * @param keyvalsep
 * The separator to use between the key and the value
 * 
 * @param endsep
 * An optional separator to use after the value.
 * 
 * @return
 * An std::vector of strings formed from each key/value pair.
 * The destruction of the object is down to the caller.
 * Use of StringUtils::destroyStringList is recommended. */
std::vector<char *> *APRTable::getAllAsStringList(const char *keyvalsep, const char *endsep)
{
   const apr_array_header_t *table_array = apr_table_elts(ttable);
   const apr_table_entry_t *table_ent = (const apr_table_entry_t *)table_array->elts;
   std::vector<char *> *tarray_strlist = new std::vector<char *>();
   for (int i = 0; i < table_array->nelts; i++)
   {
      char *varp = StringUtils::varprintf("%s%s%s%s", table_ent[i].key, keyvalsep, table_ent[i].val, endsep);
      tarray_strlist->push_back(varp);
   }
   return tarray_strlist;
}
